﻿//using System;
//using Microsoft.Xna.Framework;
//using Microsoft.Xna.Framework.Graphics;
//using Microsoft.Xna.Framework.Input;

//using LuaInterface;
//using System.Collections;
//using System.Collections.Generic;

//namespace catch_me_ai {
//    /// <summary>
//    /// This is the main type for your game
//    /// </summary>
//    public class Game:Microsoft.Xna.Framework.Game {
//        private readonly float DISTANCIA_PANICO = 116.0f;

//        GraphicsDeviceManager graphics;
//        SpriteBatch spriteBatch;
//        Texture2D imagemNPC;
//        Texture2D imagemJogador;
//        Texture2D imagemObstaculo01;
//        Texture2D imagemJogadorKeith;
//        NPC npc;
//        NPC inimigo;

//        List<Tile> imgsMapa;
//        Mapa objMapa;

//        Jogador jogador;
//        Jogador jogadorKeith;

//        bool carregouKeith = false;
//        bool pressionandoTeclado = false;
//        bool carregouInimigo = false;

//        private static Lua lua;


//        public Game() {
//            graphics = new GraphicsDeviceManager(this);
//            graphics.PreferredBackBufferWidth = 900;
//            graphics.PreferredBackBufferHeight = 600;
//            Content.RootDirectory = "Content";
//        }

//        /// <summary>
//        /// Allows the game to perform any initialization it needs to before starting to run.
//        /// This is where it can query for any required services and load any non-graphic
//        /// related content.  Calling base.Initialize will enumerate through any components
//        /// and initialize them as well.
//        /// </summary>
//        protected override void Initialize() {
//            // TODO: Add your initialization logic here
//            base.Initialize();
//            Vector2 direcao = new Vector2((float) Math.Cos(0.0f), (float) Math.Sin(0.0f));
//            npc = new NPC(this, new Vector2(600, 100), direcao, Content.Load<Texture2D>("personagens/alvo"), DISTANCIA_PANICO);
//            inimigo = new NPC(this, new Vector2(600, 100), direcao, Content.Load<Texture2D>("personagens/inimigo"), DISTANCIA_PANICO);
//            jogador = new Jogador(this, new Vector2(500, 100), direcao, 1);
//            jogadorKeith = new Jogador(this, new Vector2(30, 470), direcao, 2);
//            objMapa = new Mapa(this, "mapas.lua", "levelPadrao_map2");
//        }

//        /// <summary>
//        /// LoadContent will be called once per game and is the place to load
//        /// all of your content.
//        /// </summary>
//        protected override void LoadContent() {
//            // Create a new SpriteBatch, which can be used to draw textures.
//            spriteBatch = new SpriteBatch(GraphicsDevice);
//            imagemNPC = Content.Load<Texture2D>("personagens/alvo");
//            imagemJogador = Content.Load<Texture2D>("personagens/jogador");
//            imagemJogadorKeith = Content.Load<Texture2D>("personagens/keith");

//            imgsMapa = new List<Tile>();
//            imgsMapa.Add(new Tile(Content.Load<Texture2D>("mapa/branco"), TileCollision.Passable));
//            imgsMapa.Add(new Tile(Content.Load<Texture2D>("mapa/preto"), TileCollision.Impassable));
//            imgsMapa.Add(new Tile(Content.Load<Texture2D>("mapa/branco"), TileCollision.Passable));
//            imgsMapa.Add(new Tile(Content.Load<Texture2D>("mapa/branco"), TileCollision.Passable));

//            imagemObstaculo01 = Content.Load<Texture2D>("cenario/obstaculo01");

//            // TODO: use this.Content to load your game content here

//        }

//        /// <summary>
//        /// UnloadContent will be called once per game and is the place to unload
//        /// all content.
//        /// </summary>
//        protected override void UnloadContent() {
//            // TODO: Unload any non ContentManager content here
//        }

//        /// <summary>
//        /// Allows the game to run logic such as updating the world,
//        /// checking for collisions, gathering input, and playing audio.
//        /// </summary>
//        /// <param name="gameTime">Provides a snapshot of timing values.</param>
//        protected override void Update(GameTime gameTime) {
//            // Allows the game to exit
//            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
//                this.Exit();

//            // TODO: Add your update logic here
//            float secs = (float) gameTime.ElapsedGameTime.TotalSeconds;
//            Vector2 steeringForce = new SteerBehaviors().calculateWander(npc, 10.0f, 180.0f, 50.0f, secs);

//            Vector2 steeringForce2 = new SteerBehaviors().calculateFleeArrive(npc, jogador.getPosicao(), secs, 116.0f);
//            calculaMovimento(steeringForce2, secs, imagemNPC);

//            Vector2 steeringForce3 = new SteerBehaviors().calculateWander(inimigo, 10.0f, 180.0f, 50.0f, secs);
//            calculaMovimentoInimigo(steeringForce3, secs, inimigo);

//            #region "Mapa"
//            // Recebe o estado do teclado
//            KeyboardState keyboardState = Keyboard.GetState();

//            pressionandoTeclado = false;
//            // Verifica se o jogador pressionou seta para cima
//            if (keyboardState.IsKeyDown(Keys.Up)) {
//                jogadorKeith.setDirecao(new Vector2(0, -1));
//                pressionandoTeclado = true;
//            }
//            // Verifica se o jogador pressionou seta para baixo
//            if (keyboardState.IsKeyDown(Keys.Down)) {
//                jogadorKeith.setDirecao(new Vector2(0, 1));
//                pressionandoTeclado = true;
//            }
//            // Verifica se o jogador pressionou seta para direita
//            if (keyboardState.IsKeyDown(Keys.Right)) {
//                jogadorKeith.setDirecao(new Vector2(1, 0));
//                pressionandoTeclado = true;
//            }
//            // Verifica se o jogador pressionou seta para esqueda
//            if (keyboardState.IsKeyDown(Keys.Left)) {
//                jogadorKeith.setDirecao(new Vector2(-1, 0));
//                pressionandoTeclado = true;
//            }

//            // Define a nova posição do personagem
//            Vector2 newPosition = jogadorKeith.getPosicao();
//            newPosition.X += jogadorKeith.getDirecao().X * jogadorKeith.getVelocidade();
//            newPosition.Y += jogadorKeith.getDirecao().Y * jogadorKeith.getVelocidade();

//            // Define os tiles vizinhos do personagem conforme a nova posição
//            int left = (int) (newPosition.X / 15);
//            int top = (int) (newPosition.Y / 15);
//            int right = (int) ((newPosition.X + (imagemJogadorKeith.Width - 1)) / 15);
//            int bottom = (int) ((newPosition.Y + (imagemJogadorKeith.Height - 1)) / 15);

//            // Verifica colisão do personagem com todos os tiles vizinhos definidos ao deslocar-se
//            if (jogadorKeith.getDirecao().Y == -1) // Se o personagem esta indo para Cima
//            {
//                if (CheckTileCollision(left, top) || CheckTileCollision(right, top)) {
//                    jogadorKeith.setDirecao(new Vector2(jogadorKeith.getDirecao().X, 0.0f));
//                }
//            } else if (jogadorKeith.getDirecao().Y == 1) // Se o personagem esta indo para baixo            
//            {
//                if (CheckTileCollision(left, bottom) || CheckTileCollision(right, bottom)) {
//                    jogadorKeith.setDirecao(new Vector2(jogadorKeith.getDirecao().X, 0.0f));
//                }
//            }

//            if (jogadorKeith.getDirecao().X == 1) // Se o personagem esta indo para direita
//            {
//                if (CheckTileCollision(right, top) || CheckTileCollision(right, bottom)) {
//                    jogadorKeith.setDirecao(new Vector2(0.0f, jogadorKeith.getDirecao().Y));
//                }
//            } else if (jogadorKeith.getDirecao().X == -1) // Se o personagem esta indo para esquerda          
//            {
//                if (CheckTileCollision(left, top) || CheckTileCollision(left, bottom)) {
//                    jogadorKeith.setDirecao(new Vector2(0.0f, jogadorKeith.getDirecao().Y));
//                }
//            }

//            if (pressionandoTeclado) {
//                // Atualiza a posição do personagem
//                Vector2 position = jogadorKeith.getPosicao();
//                position = jogadorKeith.getPosicao() + jogadorKeith.getDirecao() * jogadorKeith.getVelocidade();
//                jogadorKeith.setPosicao(position);
//            }
//            #endregion "Mapa"

//            base.Update(gameTime);
//        }

//        /// <summary>
//        /// This is called when the game should draw itself.
//        /// </summary>
//        /// <param name="gameTime">Provides a snapshot of timing values.</param>
//        protected override void Draw(GameTime gameTime) {
//            GraphicsDevice.Clear(Color.CornflowerBlue);

//            spriteBatch.Begin();

//            #region "Mapa - Fazendo testes, jogarei em uma classe"
//            Vector2 posicao;

//            // Desenhando o mapa do jogo
//            for (int i = 0; i < objMapa.mapa.GetLength(0); i++) {
//                for (int j = 0; j < objMapa.mapa.GetLength(1); j++) {
//                    if (objMapa.mapa[i, j] == 2 && !carregouKeith) {
//                        posicao = new Vector2(j * imgsMapa[objMapa.mapa[i, j]].size.X, i * imgsMapa[objMapa.mapa[i, j]].size.X);
//                        jogadorKeith.setPosicao(posicao);
//                        carregouKeith = true;
//                    }
//                    if (objMapa.mapa[i, j] == 3 && !carregouInimigo) {
//                        posicao = new Vector2(j * imgsMapa[objMapa.mapa[i, j]].size.X, i * imgsMapa[objMapa.mapa[i, j]].size.X);
//                        inimigo.setPosicao(posicao);
//                        carregouInimigo = true;
//                    }

//                    spriteBatch.Draw(imgsMapa[objMapa.mapa[i, j]].texture,
//                        new Vector2(j * imgsMapa[objMapa.mapa[i, j]].size.X, i * imgsMapa[objMapa.mapa[i, j]].size.X),
//                        Color.White);
//                }
//            }
//            #endregion "Mapa"

//            spriteBatch.Draw(imagemJogadorKeith, jogadorKeith.getPosicao(), Color.White);
//            spriteBatch.Draw(inimigo.getTextura(), inimigo.getPosicao(), Color.White);

//            spriteBatch.Draw(imagemNPC, npc.getPosicao(), Color.White);
//            spriteBatch.Draw(imagemJogador, jogador.getPosicao(), Color.White);
//            spriteBatch.Draw(imagemObstaculo01, new Vector2(600, 130), Color.White);

//            base.Draw(gameTime);
//            spriteBatch.End();


//        }

//        public void calculaMovimento(Vector2 steeringForce, float segundos, Texture2D imagem) {
//            Vector2 velocidade = npc.getVelocidade();
//            Vector2 posicao = npc.getPosicao();
//            Vector2 direcao = npc.getDirecao();

//            if (steeringForce.Length() > npc.getForcaMaxima()) {
//                steeringForce.Normalize();
//                steeringForce *= npc.getForcaMaxima();
//            }

//            steeringForce *= segundos;

//            Vector2 acceleration = steeringForce / npc.getMassa();

//            velocidade += acceleration;
//            if (velocidade.Length() > npc.getVelocidadeMaxima()) {
//                velocidade.Normalize();
//                velocidade *= npc.getVelocidadeMaxima();
//            }

//            //Calcula a nova direcao
//            if (velocidade.Length() < 0.001) {
//                velocidade = new Vector2();
//            } else {
//                direcao = Vector2.Normalize(velocidade);
//            }

//            #region "Circula pela tela"

//            int w = 800; //Game.Window.ClientBounds.Width;
//            int h = 600; //Game.Window.ClientBounds.Height;

//            int npcW = imagem.Width;
//            int npcH = imagem.Height;
//            Random randon = new Random();

//            posicao += velocidade * segundos;

//            if (posicao.X < -npcW) {
//                posicao.X = w + npcW - 1;
//            } else if (posicao.X > w + npcW) {
//                posicao.X = -npcW + 1;
//            }

//            if (posicao.Y < -npcH) {
//                posicao.Y = h + npcH - 1;
//            } else if (posicao.Y > h + npcH) {
//                posicao.Y = -npcH + 1;
//            }

//            #endregion "Circula pela tela"

//            // float radiano = MathHelper.ToRadians(npc.getAngulo());
//            //  direcao = (new Vector2((float) Math.Cos(radiano), (float) Math.Sin(radiano)));

//            //    posicao = (posicao + velocidade * segundos);


//            npc.setPosicao(posicao);
//            npc.setVelocidade(velocidade);
//            npc.setDirecao(direcao * velocidade);

//        }

//        bool bateu = false;
//        public void calculaMovimentoInimigo(Vector2 steeringForce, float segundos, NPC inimigo) {
//            Vector2 velocidade = inimigo.getVelocidade();
//            Vector2 posicao = inimigo.getPosicao();
//            Vector2 direcao = inimigo.getDirecao();

//            if (steeringForce.Length() > inimigo.getForcaMaxima()) {
//                steeringForce.Normalize();
//                steeringForce *= inimigo.getForcaMaxima();
//            }

//            steeringForce *= segundos;

//            Vector2 acceleration = steeringForce / inimigo.getMassa();

//            velocidade += acceleration;
//            if (velocidade.Length() > inimigo.getVelocidadeMaxima()) {
//                velocidade.Normalize();
//                velocidade *= inimigo.getVelocidadeMaxima();
//            }

//            //Calcula a nova direcao
//            if (velocidade.Length() < 0.001) {
//                velocidade = new Vector2();
//            } else {
//                direcao = Vector2.Normalize(velocidade);
//            }

//            #region "Circula pela tela"

//            //Tamanho do quadrado do jogo
//            int w = 465;
//            int h = 405;

//            Random randon = new Random();

//            posicao += velocidade * segundos;

//            #region "Verifica colisão inimigo com cenário"

//            // Define os tiles vizinhos do personagem conforme a nova posição
//            int left = (int) (posicao.X / 15);
//            int top = (int) (posicao.Y / 15);
//            int right = (int) ((posicao.X + (inimigo.getTextura().Width - 1)) / 15);
//            int bottom = (int) ((posicao.Y + (inimigo.getTextura().Height - 1)) / 15);

//            // Verifica colisão do personagem com todos os tiles vizinhos definidos ao deslocar-se
//            if (inimigo.getDirecao().Y < 0) // Se o personagem esta indo para Cima
//                {
//                if (CheckTileCollision(left, top) || CheckTileCollision(right, top)) {
//                    bateu = true;
//                }
//            } else if (inimigo.getDirecao().Y > 0) // Se o personagem esta indo para baixo            
//                {
//                if (CheckTileCollision(left, bottom) || CheckTileCollision(right, bottom)) {
//                    bateu = true;
//                }
//            }

//            if (inimigo.getDirecao().X > 0) // Se o personagem esta indo para direita
//                {
//                if (CheckTileCollision(right, top) || CheckTileCollision(right, bottom)) {
//                    bateu = true;
//                }
//            } else if (inimigo.getDirecao().X < 0) // Se o personagem esta indo para esquerda          
//                {
//                if (CheckTileCollision(left, top) || CheckTileCollision(left, bottom)) {
//                    bateu = true;
//                }
//            }
//            #endregion "Verificar colisão inimigo com cenário"

//            #endregion "Circula pela tela"

//            //float radiano = MathHelper.ToRadians(npc.getAngulo());
//            //direcao = (new Vector2((float) Math.Cos(radiano), (float) Math.Sin(radiano)));

//            //posicao = (posicao + velocidade * segundos);
//            if (!bateu) {
//                posicao += direcao;

//                inimigo.setPosicao(posicao);
//                inimigo.setVelocidade(velocidade);
//                inimigo.setDirecao(direcao * velocidade);
//            } else {
//                //Tem que inverter a direcao do inimigo
//                posicao += -direcao;

//                inimigo.setPosicao(posicao);
//                inimigo.setVelocidade(-velocidade);
//                inimigo.setDirecao(direcao);

//                bateu = false;
//            }

//        }

//        public bool CheckTileCollision(int x, int y) {
//            if (imgsMapa[objMapa.mapa[y, x]].collision != TileCollision.Impassable) {
//                return false;
//            }
//            return true;
//        }

//        /*
//         * Método que controla qual o estado que deve ser chamado. 
//         */

//        public Vector2 maquinaEstados(float segundos, int estado) {

//            switch (estado) {
//                case 0:
//                    return npc.vagando(10.0f, 180.0f, 50.0f, segundos);

//                case 1:
//                    return npc.fugindo(jogador, segundos);

//                default:
//                    return Vector2.Zero;
//            }
//        }

//        //========= TODOs ===========//
//        //TODO: Tirar os paramêtros fixos da chamado ao método vagando no método (maquinaEstados).
//        //TODO: Descobrir o que está errado no método calculaMovimento.

//    }
//}
